﻿using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.Domain.Uow;
using Abp.Linq.Extensions;
using Abp.UI;
using Hicap.AuthorizationServer.Core.Caches.Sys;
using Hicap.AuthorizationServer.Core.Caches.Sys.Interface;
using Hicap.AuthorizationServer.Core.Models.Sys;
using Hicap.AuthorizationServer.Sys.AppService.Interface;
using Hicap.AuthorizationServer.Sys.DTO.UserRoleRelateds;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;

namespace Hicap.AuthorizationServer.Sys.AppService
{
    /// <summary>
    /// UserRoleRelated应用层服务的接口实现方法
    /// </summary>

    public class UserRoleRelatedAppService
        : AuthorizationServerAppServiceBase<UserRoleRelated, UserRoleRelatedAppService, UserRoleRelatedEditDto, UserRoleRelatedListDto, UserRoleRelatedCacheItem>, IUserRoleRelatedAppService
    {
        ////BCC/ BEGIN CUSTOM CODE SECTION
        ////ECC/ END CUSTOM CODE SECTION
        private readonly IRepository<UserRoleRelated> _userrolerelatedRepository;

        private readonly IUserCache _userCache;
        private readonly IRoleCache _roleCache;
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<Role> _roleRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        public UserRoleRelatedAppService(IRepository<UserRoleRelated> userrolerelatedRepository,
            IUserRoleRelatedCache cache,
            IRepository<UserRoleRelated> repository,
            IUserCache userCache,
            IRoleCache roleCache,
            IRepository<User> userRepository,
            IRepository<Role> roleRepository,
            IUnitOfWorkManager unitOfWorkManager) : base(
            repository,
            unitOfWorkManager,
            cache)
        {
            _userrolerelatedRepository = userrolerelatedRepository;
            _userCache = userCache;
            _roleCache = roleCache;
            _userRepository = userRepository;
            _roleRepository = roleRepository;

            ForeignKeys.Add(x => x.User);
            ForeignKeys.Add(x => x.Role);

            CreateActions.Add(SetUserRoleRelated);
            UpdateActions.Add(SetUserRoleRelatedId);
            CreateCheckActions.Add(IsDbExist);
        }

        /// <summary>
        /// 按照固定条件查询关系表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<UserRoleRelatedListDto>> PagedQueryDatas(UserRoleRelatedQueryDto input)
        {
            //            PermissionCheck();
            Func<UserRoleRelated, bool> query = (entity) =>
            {
                bool flag = true;
                if (input.RoleId.HasValue) flag = entity.Role.Id == input.RoleId && flag;
                if (input.UserId.HasValue) flag = entity.User.Id == input.UserId && flag;
                if (!string.IsNullOrEmpty(input.UserCode)) flag = entity.User != null && (entity.User.UserCode == input.UserCode && flag);
                if (!string.IsNullOrEmpty(input.RoleCode)) flag = entity.User != null && (entity.Role.RoleCode == input.RoleCode && flag);
                if (!string.IsNullOrEmpty(input.UserName)) flag = entity.User != null && (entity.User.UserName.Contains(input.UserName) && flag);
                if (!string.IsNullOrEmpty(input.RoleName)) flag = entity.User != null && (entity.Role.RoleName.Contains(input.RoleName) && flag);
                return flag;
            };

            int count = await _userrolerelatedRepository.CountAsync(x => query(x));

            List<UserRoleRelated> result = await _userrolerelatedRepository.GetAllIncluding(x => x.Role, x => x.User).Where(x => query(x))
                .OrderBy(input.Sorting)
                .PageBy(input)
                .ToListAsync();

            List<UserRoleRelatedListDto> resultListDto = result.MapTo<List<UserRoleRelatedListDto>>();

            return new PagedResultDto<UserRoleRelatedListDto>(
                count,
                resultListDto
            );
        }

        /// <summary>
        /// 重复值校验
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private void IsDbExist(UserRoleRelated entity)
        {
            bool isDbExist = false;

            if (entity.Role != null & entity.User != null)
            {
                isDbExist = _userrolerelatedRepository.GetAllIncluding(x => x.User, x => x.Role).Any(x => x.Role.Id == entity.Role.Id && x.User.Id == entity.User.Id);
            }

            if (isDbExist)
                throw new UserFriendlyException($"{L("SameRecordIsExist")}:{L("Role")},{L("User")}");
        }

        private void SetUserRoleRelatedId(UserRoleRelatedEditDto input, UserRoleRelated entity)
        {
            if (input.RoleId.HasValue) entity.Role.Id = input.RoleId.Value;
            if (input.UserId.HasValue) entity.User.Id = input.UserId.Value;
        }

        private void SetUserRoleRelated(UserRoleRelatedEditDto input, UserRoleRelated entity)
        {
            if (input.RoleId.HasValue)
            {
                //                var roleCache = await _roleCache.GetAsync(input.RoleId.Value);
                //                var role = roleCache.MapTo<Role>();
                //                entity.Role = _userrolerelatedRepository.GetDbContext().Attach(role).Entity;
                entity.Role = _roleRepository.Get(input.RoleId.Value);
            }

            if (input.UserId.HasValue)
            {
                //                var userCache = await _userCache.GetAsync(input.UserId.Value);
                //                var user = userCache.MapTo<User>();
                //                entity.User = _userrolerelatedRepository.GetDbContext().Attach(user).Entity;
                entity.User = _userRepository.Get(input.UserId.Value);
            }
        }
    }
}